/*
	jGrouse framework
	Copyright 2007 by Denis Riabtchik 
	All rights reserved.
	
	Licensed under modified BSD license. See license.txt for details
*/

/**
 * Module with support for fillers 
 * @module jgrouse.widgets.Filler
 */
jgrouse.module({
	name : 'jgrouse.widgets.Filler',
	requires : ['jgrouse.widgets.Container', 'jgrouse.widgets.WidgetProxy'],
	imports : ['jgrouse.dom.Element'],
	body : function(embed)
	{
		eval(embed);
		
		/**
		 * Basic filler of 'client' space
		 * @class jgrouse.widgets.Filler
		 * @extends jgrouse.widgets.WidgetProxy
		 */
		jgrouse.define('jgrouse.widgets.Filler', 'jgrouse.widgets.WidgetProxy', function(embed)
		{
			eval(embed);
			
			return {
				/**
				 * @constructor initialize
				 * @inheritdesc
				 */
				initialize : function(options, styles)
				{
					_sup(this, arguments);
					this.addStyles({overflow: 'hidden'});
				},
				
				/**
				 * Create a 'bucket' that wraps around children nodes
				 * @function {String} createBucket
				 * @return string containing HTML template to be used by buckets
				 */
				createBucket : function()
				{
					jgrouse.notImplemented(this.RTTI + 'createBucket');
				},
				
				/**
				 * @function getOwnTemplate
				 * @inheritdesc
				 */
				getOwnTemplate : function()
				{
					var s = "<div _jgmember='_content' style='width:100%; height:100%; overflow:hidden'></div>";
					return s;
				},	
				
				/**
				 * @function setTemplate
				 * @inheritdesc
				 */
				setTemplate : function(template)
				{
					_sup(this, arguments);
					var filler = null;
					var athis = this;
					Element.forEachNode(template._currentNode, function(node, index)
					{
						var f = Element.getAttribute(node, '_jg-filler');
						var bucket = athis.createBucket();
						if (f)
						{
							filler = bucket;
						}
						template._currentNode.replaceChild(bucket, node);
						bucket.appendChild(node); 
					}, true);
					this._filler = filler;
				}
			}
		});
		
		
		jgrouse.widgets.registerWidget('widthFiller', 'jgrouse.widgets.WidthFiller');
		
		/**
		 * Widget that fills horisontal space. Regustered under alias <b>widthFiller</b>
		 * @class jgrouse.widgets.WidthFiller
		 * @extends jgrouse.widgets.Filler
		 */
		jgrouse.define('jgrouse.widgets.WidthFiller', 'jgrouse.widgets.Filler', function(embed)
		{
			eval(embed);
			
			return {
				/**
				 * @constructor initialize
				 * @inheritdesc
				 */
				initialize : function(options, styles)
				{
					_sup(this, arguments);
					this._safetyPadding = 50;
				},
				
				/**
				 * @function createBucket
				 * @inheritdesc
				 */
				createBucket : function()
				{
					var d = document.createElement('div');
					Element.addStyle(d, {'float' : 'left', overflow : 'hidden', height:'100%'});
					return d;
				},
				
				/**
				 * @function layout
				 * @inheritdesc
				 */
				layout : function()
				{
					_sup(this, arguments);
					if (this.isShowing())
					{
						var content = this.getTargetNode();
						var width = 0;
						var athis = this;
						Element.forEachNode(content, function(node, index)
						{
							if (athis._filler != node)
							{
								width += node.offsetWidth;
							}
						});
						var parentWidth = content.parentNode.clientWidth + this._safetyPadding;
						if (parentWidth) // silly IE sometimes would leave clientWidth as 0 if the width style has not been specified
						{
							if (parentWidth < width)
							{
								Element.addStyle(content, {width: (width + this._safetyPadding) + 'px'});
							}
							else
							{
								Element.addStyle(content, {width: parentWidth+ 'px'} );
							}
						}
						var contentWidth = content.offsetWidth - this._safetyPadding;
						if (contentWidth < 0)
						{
							contentWidth = 0;
						}
						if (this._filler)
						{
							var remaining = contentWidth - width;
							if (remaining > 0)
							{
								Element.clearStyle(this._filler, 'display');
								Element.addStyle(this._filler, {width : remaining + 'px'});
							}
							else
							{
								Element.addStyle(this._filler, {width : '0px'});
								Element.addStyle(this._filler, {display : 'none'});
							}
						}
					}
				}
			}
		});

		jgrouse.widgets.registerWidget('heightFiller', 'jgrouse.widgets.HeightFiller');
		
		/**
		 * Widget that fills vertical space. Registered under alias <b>heightFiller</b>
		 * @class jgrouse.widgets.HeightFiller
		 * @extends jgrouse.widgets.Filler
		 */
		jgrouse.define('jgrouse.widgets.HeightFiller', 'jgrouse.widgets.Filler', function(embed)
		{
			eval(embed);
			
			return {
				/**
				 * @constructor initialize
				 * @inheritdesc
				 */
				initialize : function(options, styles)
				{
					_sup(this, arguments);
				},
				
				/**
				 * @function createBucket
				 * @inheritdesc
				 */
				createBucket : function()
				{
					var d = document.createElement('div');
					Element.addStyle(d, {overflow : 'hidden'});
					return d;
				},
				
				/**
				 * @function layout
				 * @inheritdesc
				 */
				layout : function()
				{
					_sup(this, arguments);
					if (this.isShowing())
					{
						var content = this.getTargetNode();
						var height = 0;
						var athis = this;
						Element.forEachNode(content, function(node, index)
						{
							if (athis._filler != node)
							{
								height += node.offsetHeight;
							}
						});
						var parentHeight = content.parentNode.clientHeight;
						if (parentHeight) // silly IE sometimes would leave clientWidth as 0 if the width style has not been specified
						{
							if (parentHeight < height)
							{
								Element.addStyle(content, {height: height + 'px'});
							}
							else
							{
								Element.addStyle(content, {height: parentHeight+ 'px'} );
							}
						}
						var contentHeight = content.offsetHeight;
						if (this._filler)
						{
							var remaining = contentHeight - height;
							if (remaining > 0)
							{
								Element.clearStyle(this._filler, 'display');
								Element.addStyle(this._filler, {height : remaining + 'px'});
							}
							else
							{
								Element.addStyle(this._filler, {height : '0px'});
								Element.addStyle(this._filler, {display : 'none'});
							}
						}
					}
				}
			}
		});

		
	}
})